﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Text;
using System.Linq.Expressions;
using System.Web.UI.WebControls.Expressions;
using System.Dynamic;


namespace CREAPA.UL.Web.HtmlHelpers
{
    public static class HtmlControlHelper
    {
        public static IHtmlString DisableableDropDownList(
            this HtmlHelper helper,
            String name,
            IEnumerable<SelectListItem> selectList,
            String optionLabel,
            Object htmlAttributes)
        {
            var generator = Funcify((Dictionary<String, Object> x) => helper.DropDownList(name, selectList, optionLabel, x).ToHtmlString());

            return DropDownList(name, htmlAttributes, generator);
        }

        public static IHtmlString DisableableDropDownListFor<TModel, TProperty>(
            this HtmlHelper<TModel> helper,
	        Expression<Func<TModel, TProperty>> expression,
	        IEnumerable<SelectListItem> selectList,
            String optionLabel,
            Object htmlAttributes)
        {
            var generator = Funcify ((Dictionary<String, Object> x) => helper.DropDownListFor(expression, selectList, optionLabel, x).ToHtmlString());

            var name = ((MemberExpression)expression.Body).Member.Name;

            return DropDownList(name, htmlAttributes, generator);
        }

        static IHtmlString DropDownList(
            String name,
            Object htmlAttributes,
            Func<Dictionary<String, Object>, String> generator)
        {
            var sb = new StringBuilder();

            // implicit width and height of the control we're creating
            // these can be overriden by explicit values stored in the htmlAttributes parameter
            var width = "250px";
            var height = "30px";

            // implicit id of the control we're creating
            var mainId = name;

            // we have to check whether the user has provided explicit values for the width, height and
            // id, therefore I loop through all the properties of the htmlAttributes object and check
            // for the properties
            var htmlAttributesDic = new Dictionary<String, Object>();

            foreach (var htmlProperty in htmlAttributes.GetType().GetProperties())
            {
                var propertyName = htmlProperty.Name;
                var propertyValue = htmlProperty.GetValue(htmlAttributes, null);

                // if we find the id property we store its value for later reference
                if (propertyName == "id")
                    mainId = propertyValue.ToString();
                // all other properties and values get stored in the attributes dictionary
                else
                {
                    if (propertyName == "style")
                    {
                        var style = propertyValue.ToString();

                        if (style.Contains("width:"))
                        {
                            var i = style.IndexOf("width:") + 6;

                            width = style.Substring(i, style.IndexOf(';', i) - i);
                        }

                        if (style.Contains("height:"))
                        {
                            var i = style.IndexOf("height:") + 6;

                            height = style.Substring(i, style.IndexOf(';', i) - i);
                        }
                    }

                    htmlAttributesDic.Add(propertyName, propertyValue);
                }
            }

            // the id of the actual dropdown list will be ddl_[mainId]
            htmlAttributesDic.Add("id", "ddl_" + mainId);

            var ddl = generator(htmlAttributesDic); 
            sb.AppendLine(ddl);

            var hiderSpan = @"<span id='span_Hider' style='position: absolute;left:0;z-index:-1;opacity:0.4;filter: alpha(opacity = 50); width:" + width + ";height:" + height + ";'></span>";
            sb.AppendLine(hiderSpan);

            // the outer span element will have the id that the user passed in or the name of the 
            // property for which the dropdown list is created for if no id is provided
            var s = "<span id='" + mainId + "' style='position:relative; width:" + width + ";height:" + height + ";'>" + sb.ToString() + "</span>";

            s += @"
                <script type='text/javascript'>
                    $(document).ready(function () {
                        $.fn.extend({
                            disableDropDownList: function () {
                                var $ddl = $(this);

                                $ddl.find('#span_Hider').css('z-index', '1');
                            },
                            enableDropDownList: function () {
                                var $ddl = $(this);

                                $ddl.find('#span_Hider').css('z-index', '-1');
                            }
                        });
                    });
                </script>";

            return new HtmlString(s.ToString());
        }

        public static Func<T, TResult> Funcify<T, TResult>(Func<T, TResult> f)
        { 
            return f; 
        }
    }
}